package net.lab1024.sa.admin.module.system.config;

import net.lab1024.sa.admin.module.system.config.domain.vo.SystemConfigDefaultVO;
import net.lab1024.sa.admin.module.system.config.domain.SystemConfigEntity;
import net.lab1024.sa.admin.module.system.config.domain.vo.SystemConfigPainetBoxVO;
import net.lab1024.sa.base.common.constant.SystemKeyConst;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SystemConfigService {

    private static final String CACHE_PREFIX = "SYSTEM:CONFIG:PREFIX:";

    private final SystemConfigDao systemConfigDao;

    private final RedisTemplate<String, Object> redisTemplate;

    public SystemConfigService(SystemConfigDao systemConfigDao,
                               RedisTemplate<String, Object> redisTemplate) {
        this.systemConfigDao = systemConfigDao;
        this.redisTemplate = redisTemplate;
    }

    public List<SystemConfigEntity> getByKeyPrefix(String keyPrefix) {
        return systemConfigDao.getByKeyPrefix(keyPrefix);
    }

    /**
     * 保存配置
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> save(String prefix, Map<String, Object> params) {
        if (ObjectUtils.isEmpty(prefix)) {
            return ResponseDTO.userErrorParam("配置前缀为空");
        }
        if (params == null || params.isEmpty()) {
            return ResponseDTO.userErrorParam("配置参数为空");
        }
        // 校验前缀
        Boolean contains = SystemKeyConst.containsPrefix(prefix);
        if (!contains) {
            return ResponseDTO.userErrorParam("数据异常");
        }
        // 校验所有key
        SystemKeyConst.Config config = SystemKeyConst.getConfig(prefix);
        Boolean containsAllKey = config.containsAllKey(params.keySet());
        if (!containsAllKey) {
            return ResponseDTO.userErrorParam("数据Key异常");
        }
        // 数据准备
        List<SystemConfigEntity> list = new ArrayList<>();
        params.forEach((k, v) -> {
            SystemConfigEntity entity = new SystemConfigEntity();
            entity.setConfigKey(k);
            entity.setConfigValue(v != null ? v.toString() : null);
            list.add(entity);
        });
        // 写入数据库
        systemConfigDao.insertBatchKeys(list);
        redisTemplate.delete(CACHE_PREFIX + prefix);
        return ResponseDTO.ok();
    }

    public String getValueByKey(String key) {
        return systemConfigDao.getValueByKey(key);
    }

    /**
     * 获取默认配置
     */
    public ResponseDTO<SystemConfigDefaultVO> getDefault() {
        // 初始返回值
        SystemConfigDefaultVO systemConfigDefaultVO = new SystemConfigDefaultVO();
        // 根据前缀查询
        List<SystemConfigEntity> systemConfigEntityList =
                systemConfigDao.getByKeyPrefix(SystemKeyConst.DefaultConfig.KEY_PREFIX);
        // 列表为空直接返回空的VO
        if (CollectionUtils.isEmpty(systemConfigEntityList)) {
            return ResponseDTO.ok(systemConfigDefaultVO);
        }
        // 结果转成map
        Map<String, String> collect = systemConfigEntityList.stream()
                .collect(Collectors.toMap(SystemConfigEntity::getConfigKey, SystemConfigEntity::getConfigValue));
        // 赋值默认配置VO
        String defaultUpstream = collect.get(SystemKeyConst.DefaultConfig.UPSTREAM);
        if (!ObjectUtils.isEmpty(defaultUpstream)) {
            systemConfigDefaultVO.setDefaultUpstream(Integer.valueOf(defaultUpstream));
        }
        return ResponseDTO.ok(systemConfigDefaultVO);
    }

    /**
     * 获取派盒子配置
     */
    public ResponseDTO<SystemConfigPainetBoxVO> getPainetBox() {
        String key = CACHE_PREFIX + SystemKeyConst.PainetBoxConfig.KEY_PREFIX;
        Object configCache = redisTemplate.opsForValue().get(key);
        // 先取缓存拿
        if (configCache != null) {
            return ResponseDTO.ok((SystemConfigPainetBoxVO) configCache);
        }
        // 初始返回值
        SystemConfigPainetBoxVO systemConfigPainetBoxVO = new SystemConfigPainetBoxVO();
        // 根据前缀查询
        List<SystemConfigEntity> systemConfigEntityList =
                systemConfigDao.getByKeyPrefix(SystemKeyConst.PainetBoxConfig.KEY_PREFIX);
        // 列表为空直接返回空的VO
        if (CollectionUtils.isEmpty(systemConfigEntityList)) {
            return ResponseDTO.ok(systemConfigPainetBoxVO);
        }
        // 结果转成map
        Map<String, String> collect = systemConfigEntityList.stream()
                .collect(Collectors.toMap(SystemConfigEntity::getConfigKey, SystemConfigEntity::getConfigValue));
        // 赋值派盒子配置VO
        String painetBoxAccount = collect.get(SystemKeyConst.PainetBoxConfig.ACCOUNT);
        if (!ObjectUtils.isEmpty(painetBoxAccount)) {
            systemConfigPainetBoxVO.setPainetBoxAccount(painetBoxAccount);
        }
        String painetBoxAK = collect.get(SystemKeyConst.PainetBoxConfig.AK);
        if (!ObjectUtils.isEmpty(painetBoxAK)) {
            systemConfigPainetBoxVO.setPainetBoxAK(painetBoxAK);
        }
        String painetBoxAS = collect.get(SystemKeyConst.PainetBoxConfig.AS);
        if (!ObjectUtils.isEmpty(painetBoxAS)) {
            systemConfigPainetBoxVO.setPainetBoxAS(painetBoxAS);
        }
        String painetBoxServerUrl = collect.get(SystemKeyConst.PainetBoxConfig.SERVER_URL);
        if (!ObjectUtils.isEmpty(painetBoxServerUrl)) {
            systemConfigPainetBoxVO.setPainetBoxServerUrl(painetBoxServerUrl);
        }
        String painetBoxCuccPrice = collect.get(SystemKeyConst.PainetBoxConfig.CUCC_PRICE);
        if (!ObjectUtils.isEmpty(painetBoxCuccPrice)) {
            systemConfigPainetBoxVO.setPainetBoxCuccPrice(Integer.parseInt(painetBoxCuccPrice));
        }
        String painetBoxCtccPrice = collect.get(SystemKeyConst.PainetBoxConfig.CTCC_PRICE);
        if (!ObjectUtils.isEmpty(painetBoxCtccPrice)) {
            systemConfigPainetBoxVO.setPainetBoxCtccPrice(Integer.parseInt(painetBoxCtccPrice));
        }
        String painetBoxCmccPrice = collect.get(SystemKeyConst.PainetBoxConfig.CMCC_PRICE);
        if (!ObjectUtils.isEmpty(painetBoxCmccPrice)) {
            systemConfigPainetBoxVO.setPainetBoxCmccPrice(Integer.parseInt(painetBoxCmccPrice));
        }
        // 放入缓存
        redisTemplate.opsForValue().set(key, systemConfigPainetBoxVO);
        return ResponseDTO.ok(systemConfigPainetBoxVO);
    }

}
